package name.sakanacatcher.service;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import name.sakanacatcher.entity.Group;
import name.sakanacatcher.entity.Message;
import name.sakanacatcher.entity.User;
import name.sakanacatcher.repository.MessageRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

@ServerEndpoint("/webSocket/{username}")
@Service
public class WebSocketService {


    public static InformService informService;

    public static UserService userService;


    //静态变量，用来记录当前在线连接数。应该把它设计成线程安全的。
    private static AtomicInteger onlineNum = new AtomicInteger();

    //concurrent包的线程安全Set，用来存放每个客户端对应的WebSocketServer对象。
    private static ConcurrentHashMap<String,Session> sessionPools = new ConcurrentHashMap<>();

    //发送消息
    public void sendMessage(Session session, String message,String items) throws IOException {
        if(session != null){
            synchronized (session) {
                System.out.println(session.getId());
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("message",message);
                jsonObject.put("items",items);
                session.getBasicRemote().sendText(jsonObject.toString());
            }
        }
    }
    public void sendMessage(Session session, String message) throws IOException {
        if(session != null){
            synchronized (session) {
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("message", message);
                session.getBasicRemote().sendText(jsonObject.toJSONString());
            }
        }
    }
    //给指定用户发送信息
    public void sendInfo(String username, String message){
        Session session = sessionPools.get(username);
        try {
            sendMessage(session, message);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    //建立连接成功调用
    @OnOpen
    public void onOpen(Session session,@PathParam(value = "groupName") String groupName, @PathParam(value = "username") String username){
        sessionPools.put(username,session);
        addOnlineCount();
        System.out.println(username + "加入webSocket！当前人数为" + onlineNum);
        try {
            sendMessage(session, "欢迎" + username + "加入连接！");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //关闭连接时调用
    @OnClose
    public void onClose(@PathParam(value = "groupName") String groupName,@PathParam(value = "username") String username){
        System.out.println(sessionPools.keySet());
        sessionPools.remove(username);
        subOnlineCount();
        System.out.println(username + "断开webSocket连接！当前人数为" + onlineNum);
    }

    //收到客户端信息
    @OnMessage
    public void onMessage(String jsonString) throws IOException{
        JSONObject jsonObject = JSONObject.parseObject(jsonString);
        if(jsonObject.getString("message").equals("new dialog")) {
            System.out.println(jsonString);
            MessageRepository messageRepository = informService.getMessageRepository();
            Message msg =  messageRepository.findById(informService.sendMessage(jsonObject));
            System.out.println(jsonObject.getString("groupName"));

            List<User> users = informService.getGroupRepository().getGroupByName(jsonObject.getString("groupName")).getUsers();
            System.out.println(users);
            ObjectMapper mapper = new ObjectMapper();
            String json = mapper.writeValueAsString(msg);
            boolean flag = true;
            for(User user:users){
                System.out.println(sessionPools.keySet());
                if(sessionPools.containsKey(user.getUsername())){
                    try {
                        System.out.println("正在发送给" + user.getUsername());
                        sendMessage(sessionPools.get(user.getUsername()), "new dialog", json);
                    } catch (Exception e) {
                        e.printStackTrace();
                        continue;
                    }

                }
                if(user.getId() == jsonObject.getInteger("senderId")){
                    flag = false;
                }
            }
            if(flag){
                try {
                    User user = userService.getUserRepository().getById((int)(jsonObject.getInteger("senderId")));
                    System.out.println("正在发送给" + user.getUsername());
                    sendMessage(sessionPools.get(user.getUsername()), "new dialog", json);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        else {
            for (Session session : sessionPools.values()) {
                try {
                    sendMessage(session, jsonObject.getString("message"));
                } catch (Exception e) {
                    e.printStackTrace();
                    continue;
                }
            }
        }
    }

    //错误时调用
    @OnError
    public void onError(Session session, Throwable throwable){
        System.out.println("发生错误");
        throwable.printStackTrace();
    }

    public static void addOnlineCount(){
        onlineNum.incrementAndGet();
    }

    public static void subOnlineCount() {
        onlineNum.decrementAndGet();
    }

    @Autowired
    public void setInformService (InformService informService){
        WebSocketService.informService = informService;
    }
    @Autowired
    public void setUserService (UserService userService){
        WebSocketService.userService = userService;
    }
}
